package com.rzl.expense.framework.aspectj;

import com.rzl.expense.common.core.domain.entity.SysRegion;
import com.rzl.expense.common.core.domain.entity.SysRole;
import com.rzl.expense.common.core.domain.entity.SysUser;
import com.rzl.expense.common.utils.SecurityUtils;
import com.rzl.expense.common.utils.ServletUtils;
import com.rzl.expense.common.utils.StringUtils;
import com.rzl.expense.common.utils.spring.SpringUtils;
import com.rzl.expense.system.mapper.SysRegionMapper;
import com.rzl.expense.system.mapper.SysRoleRegionMapper;
import com.rzl.expense.system.mapper.SysUserMapper;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 数据过滤处理
 *
 * @author expense
 */
@Aspect
@Component
public class ContractScopeAspectV2 {
    /**
     * 全部数据权限
     */
    public static final String DATA_SCOPE_ALL = "1";

    /**
     * 自定数据权限
     */
    public static final String DATA_SCOPE_CUSTOM = "2";

    /**
     * 地市数据权限
     */
    public static final String DATA_SCOPE_CITY = "3";

    /**
     * 地市及以下数据权限
     */
    public static final String DATA_SCOPE_COUNTY = "4";

    /**
     * 仅本人数据权限
     */
    public static final String DATA_SCOPE_SELF = "5";

    public static final String PROVIDE_ID = "220000";


    public static String dataScopeFilterV1() {
        StringBuilder sqlString = new StringBuilder();
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        //根据角色所有数据权限
        if (sysUser.getRoles().size() == 1 && sysUser.getRoles().get(0).getDataScope().equals(DATA_SCOPE_SELF)){
            sqlString.append(StringUtils.format(" OR dc.create_user = '{}' " , sysUser.getUserName()));
            return getString(sqlString);
        }
        List<String> regIds = getDataPerm(sysUser.getRoles(),sysUser);
        if (!regIds.isEmpty()){
            sqlString.append(StringUtils.format(" OR dc.reg_id IN ( '{}' ) OR dc.preg_id IN ('{}') ", StringUtils.join(regIds, "','"), StringUtils.join(regIds, "','")));
            sqlString.append(StringUtils.format(" OR dc.create_user = '{}' " , sysUser.getUserName()));
            return getString(sqlString);
        }
        return "";
    }
    public static String dataScopeFilterV2() {
        StringBuilder sqlString = new StringBuilder();
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        List<String> dataPerm = getDataPerm(sysUser);
        if (!dataPerm.isEmpty()){
            sqlString.append(StringUtils.format(" OR dc.create_user IN ( '{}' ) ", StringUtils.join(dataPerm, "','")));
            return getString(sqlString);
        }
        return "";
    }
    private static String getString(StringBuilder sqlString) {
        if (StringUtils.isNotEmpty(sqlString)) {
            return " AND (" + sqlString.substring(4) + ")";
        }
        return "";
    }

    private static List<String> getDataPerm(List<SysRole> roles, SysUser sysUser) {
        HashSet<String> regIdSet = new HashSet<>();
        SysRegionMapper regionMapper = SpringUtils.getBean(SysRegionMapper.class);
        SysRoleRegionMapper roleRegionMapper = SpringUtils.getBean(SysRoleRegionMapper.class);
        boolean isCityLevel = PROVIDE_ID.equals(sysUser.getRegId());
        // 预先查询是否有子节点，避免重复调用
        int hasChild = regionMapper.hasChildByRegionId(sysUser.getRegId());
        for (SysRole role : roles) {
            String dataScope = role.getDataScope();
            switch (dataScope) {
                case DATA_SCOPE_ALL:
                    return new ArrayList<>(); // 全部数据权限，返回空集合表示无限制
                case DATA_SCOPE_CUSTOM:
                    // 自定义数据权限
                    regIdSet.addAll(roleRegionMapper.selectRegIdByRoleId(role.getRoleId()));
                    break;
                case DATA_SCOPE_CITY:
                case DATA_SCOPE_COUNTY:
                    // 地市判断
                    if (isCityLevel) {
                        return new ArrayList<>();
                    }
                    // 根据是否有子区域进行处理
                    if (hasChild > 0) {
                        if (DATA_SCOPE_CITY.equals(dataScope)) {
                            regIdSet.addAll(regionMapper.selectRegionIdByRegidV2(sysUser.getRegId()));
                        } else {
                            regIdSet.addAll(regionMapper.selectRegionIdByRegidV1(sysUser.getRegId()));
                        }
                    } else {
                        regIdSet.add(sysUser.getRegId());
                    }
                    break;
                default:
                    break;
            }
        }
        return new ArrayList<>(regIdSet);
    }
    private static List<String> getDataPerm(SysUser sysUser) {
        HashSet<String> nameSet = new HashSet<>();
        List<SysRole> roles = sysUser.getRoles();
        SysUserMapper userMapper = SpringUtils.getBean(SysUserMapper.class);
        SysRegionMapper regionMapper = SpringUtils.getBean(SysRegionMapper.class);

        for (SysRole role : roles) {
            if (DATA_SCOPE_ALL.equals(role.getDataScope())){
                return new ArrayList<>();
            }
            if (DATA_SCOPE_CUSTOM.equals(role.getDataScope())){
                nameSet.addAll(userMapper.selectUsernameByRoleId(role.getRoleId()));
                continue;
            }
            if (DATA_SCOPE_CITY.equals(role.getDataScope())){
                int hasChild = regionMapper.hasChildByRegionId(sysUser.getRegId());
                if (PROVIDE_ID.equals(sysUser.getRegId()) || hasChild>0){
                    nameSet.addAll(userMapper.selectRegUserChildByRegId(sysUser.getRegId()));
                }else {
                    SysRegion region = regionMapper.selectRegionById(sysUser.getRegId());
                    nameSet.addAll(userMapper.selectRegUserChildByRegId(region.getRegId()));
                }
                continue;
            }
            if (DATA_SCOPE_COUNTY.equals(role.getDataScope())){
                nameSet.addAll(userMapper.selectRegUserChildByRegId(sysUser.getRegId()));
                continue;
            }
            if (DATA_SCOPE_SELF.equals(role.getDataScope())){
                nameSet.add(sysUser.getUserName());
            }
        }
        return new ArrayList<>(nameSet);
    }
}
